#include <sstream>
#include <boost/chrono/thread_clock.hpp>
#include "FlexScanner.h"
#include "BisonParser.h"    // yy::BisonParser
#include "MessageParser.h"
#include "../mime/data/Entity.h"
#include "../mime/core/MessageReprConverter.h"

//#define DEBUG

using namespace kc_sf;

// ----------------------------------------------------- //

MessageParser::MessageParser( const RawMessage &rmsg )
: mp_raw_message( rmsg )
{
}

// ----------------------------------------------------- //

bool MessageParser::parse( Message &msg )
{
    using namespace boost::chrono;

	std::stringstream input( mp_raw_message.rmData );
	FlexScanner scanner( &input ); // klasa skanera (flex)

	Entity *top_entity = new Entity(),
		*act_entity = top_entity;

#ifdef DEBUG
    thread_clock::time_point start = thread_clock::now();
#endif // DEBUG

	yy::BisonParser	parser( // klasa parsera (bison)
		&scanner,	// przekazuje do parsera obiekt skanera
		top_entity,	// przekazuje parserowi do ustawienia nadrzędną encję wiadomości
		act_entity		// przekazuje do parsera instancje aktualnie przetwarzanej encji
	);

    bool success = ( parser.parse() == 0 ) ? true : false;

#ifdef DEBUG
    thread_clock::time_point stop = thread_clock::now();
    std::cout << "---> Parser: " << duration_cast<milliseconds>(stop - start).count() << " ms" << std::endl;
#endif // DEBUG

    msg = MessageReprConverter()( *top_entity, mp_raw_message );

    delete top_entity;

    return success;
}
